package cn.flightcloud.auth.config.spring.security;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.vote.AffirmativeBased;
import org.springframework.security.access.vote.RoleVoter;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;

import cn.flightcloud.auth.config.spring.security.metadata.RefreshSecurityMetadataSource;
import cn.flightcloud.auth.config.spring.security.provider.SimpleAuthenticationProvider;
import cn.flightcloud.auth.config.spring.security.service.SimpleUserDetailsService;

//@Configuration
//@EnableWebSecurity // 开启spring-security
//@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
//@Order(1)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

	@Autowired
	private AuthenticationManager authenticationManager;
	@Autowired
	private PasswordEncoder passwordEncoder;

	@Bean
	@Override
	protected AuthenticationManager authenticationManager() throws Exception {
		return super.authenticationManager();
	}

	@Bean
	public AuthenticationProvider authenticationProvider() {
		SimpleAuthenticationProvider provider = new SimpleAuthenticationProvider(userDetailsService());
		provider.setPasswordEncoder(passwordEncoder);
		return provider;
	}

	@Bean
	public PasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder();
	}

	@Bean
	@Override
	protected UserDetailsService userDetailsService() {
		UserDetailsService userDetailsService = new SimpleUserDetailsService();
		return userDetailsService;
	}

	@Bean
	public RefreshSecurityMetadataSource refreshSecurityMetadataSource() {
		RefreshSecurityMetadataSource refreshSecurityMetadataSource = new RefreshSecurityMetadataSource();
		return refreshSecurityMetadataSource;
	}

	@Bean
	public AccessDecisionManager accessDecisionManager() {
		RoleVoter roleVoter = new RoleVoter();
		roleVoter.setRolePrefix("");
		List<AccessDecisionVoter<?>> list = new ArrayList<>();
		list.add(roleVoter);
		AccessDecisionManager accessDecisionManager = new AffirmativeBased(list);
		return accessDecisionManager;
	}

	@Bean
	public FilterSecurityInterceptor filterSecurityInterceptor() {
		FilterSecurityInterceptor filterSecurityInterceptor = new FilterSecurityInterceptor();
		filterSecurityInterceptor.setSecurityMetadataSource(refreshSecurityMetadataSource());
		filterSecurityInterceptor.setAccessDecisionManager(accessDecisionManager());
		return filterSecurityInterceptor;
	}

	@Override
	protected void configure(HttpSecurity http) throws Exception {

		// @formatter:off
		// http.formLogin().loginPage("/login").failureUrl("/login?error").defaultSuccessUrl("/")
		// .usernameParameter("username").passwordParameter("password").permitAll().and().antMatcher("/oauth/**")
		// .permitAll().and()
		// // 除以上路径都需要验证
		// .authorizeRequests().anyRequest().authenticated();
		// @formatter:on

		// @formatter:off
		http.csrf().disable() // HTTP with Disable CSRF
				.authorizeRequests().antMatchers("/login", "/css/**", "/image/*").permitAll()//
				.antMatchers("/oauth/**").permitAll()//
				.and().formLogin().loginPage("/login")// 设置登录页面
				.defaultSuccessUrl("/")// 设置默认登录成功跳转页面
				.failureUrl("/login?error").permitAll()// 设置登录失败的页面
				.and().logout().logoutUrl("/logout")// 设置logout页面
				.and().authorizeRequests().anyRequest().authenticated();// 任何请求,登录后可以访问
//		http.oauth2Login().redirectionEndpoint();
		http.addFilterBefore(filterSecurityInterceptor(), FilterSecurityInterceptor.class);
		// @formatter:on
	}

	@Override
	@ConditionalOnBean
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.authenticationProvider(authenticationProvider());
		auth.parentAuthenticationManager(authenticationManager);
	}

	@Override
	public void configure(WebSecurity web) throws Exception {
		// 忽略css.jq.img等文件
		web.ignoring().antMatchers("/**.html", "/**.css", "/img/**", "/**.js", "/third-party/**");
	}
}
